
#include "../jthread.h"
#include "../jmutexautolock.h"
#include "../../HttpSer.h"

#ifndef _WIN32_WCE
	#include <process.h>
#endif // _WIN32_WCE

namespace jthread
{
//NODETHREAD JThread::m_pThread = NULL;

JThread::JThread()
{
	retval = NULL;
	mutexinit = false;
	running = false;
	threadhandle = NULL;
}

JThread::~JThread()
{
	Kill();
	if(threadhandle)
	{
		printf("CloseHandle\n");
		CloseHandle(threadhandle);
		threadhandle = NULL;
	}
}

int JThread::Start()
{
	if (!mutexinit)
	{
		if (!runningmutex.IsInitialized())
		{
			if (runningmutex.Init() < 0)
				return ERR_JTHREAD_CANTINITMUTEX;
		}
		if (!continuemutex.IsInitialized())
		{
			if (continuemutex.Init() < 0)
				return ERR_JTHREAD_CANTINITMUTEX;
		}
		if (!continuemutex2.IsInitialized())
		{
			if (continuemutex2.Init() < 0)
				return ERR_JTHREAD_CANTINITMUTEX;
		}		mutexinit = true;
	}
	
	runningmutex.Lock();
	if (running)
	{
		runningmutex.Unlock();
		return ERR_JTHREAD_ALREADYRUNNING;
	}
	runningmutex.Unlock();
	
	continuemutex.Lock();
#ifndef _WIN32_WCE
	threadhandle = (HANDLE)_beginthreadex(NULL,0,TheThread,this,0,&threadid);
#else
	threadhandle = CreateThread(NULL,0,TheThread,this,0,&threadid);
#endif // _WIN32_WCE
	if (threadhandle == NULL)
	{
		continuemutex.Unlock();
		return ERR_JTHREAD_CANTSTARTTHREAD;
	}
	
	/* Wait until 'running' is set */

	runningmutex.Lock();			
	while (!running)
	{
		runningmutex.Unlock();
		Sleep(1);
		runningmutex.Lock();
	}
	runningmutex.Unlock();
	
	continuemutex.Unlock();
	
	continuemutex2.Lock();
	continuemutex2.Unlock();
		
	return 0;
}

int JThread::Kill()
{
	runningmutex.Lock();			
	if (!running)
	{
		runningmutex.Unlock();
		return ERR_JTHREAD_NOTRUNNING;
	}
	//printf("TerminateThread start \n");
	if(threadhandle)
	{
		//printf("CloseHandle start\n");
		CloseHandle(threadhandle);
		//printf("CloseHandle end\n");
		threadhandle = NULL;
	}
	//TerminateThread(threadhandle,0);
	//printf("TerminateThread ok \n");
	running = false;
	runningmutex.Unlock();
	return 0;
}

bool JThread::IsRunning()
{
	bool r;
	
	runningmutex.Lock();			
	r = running;
	runningmutex.Unlock();
	return r;
}

void *JThread::GetReturnValue()
{
	JMutexAutoLock autolock(runningmutex);
	void *val;
	
	if (running)
		val = NULL;
	else
		val = retval;
	return val;
}
void JThread::SetThreadRunSate(bool Run,void* ret)
{
	JMutexAutoLock autolock(runningmutex);
	running = Run;
	if(this)
		retval = ret;
}

#ifndef _WIN32_WCE
UINT __stdcall JThread::TheThread(void *param)
#else
DWORD WINAPI JThread::TheThread(void *param)
#endif // _WIN32_WCE
{
	JThread *jthread;
	jthread = (JThread *)param;
	//HANDLE  hThread = jthread->threadhandle;
	
	jthread->continuemutex2.Lock();
	jthread->SetThreadRunSate(true);
	//jthread->runningmutex.Lock();
	//jthread->running = true;
	//jthread->runningmutex.Unlock();
	
	//jthread->continuemutex.Lock();
	//jthread->continuemutex.Unlock();
	
	/*void *ret = NULL;*/
	//return (UINT)JThreadFnc(param);
	//return (UINT)CHttpSer::pHttp->JThreadFunc(param);
	//if(jthread->threadhandle)
	//{
	//	CloseHandle(jthread->threadhandle);
	//	jthread->threadhandle = NULL;
	//}
	
	//jthread->runningmutex.Lock();
	//jthread->running = false;
	//jthread->retval = ret;
	//jthread->runningmutex.Unlock();
	jthread->Thread();
	return (UINT)0;		
}

void JThread::ThreadStarted()
{
	continuemutex2.Unlock();
}

} // end namespace


void JThread::ExitThread()
{
	runningmutex.Lock();
	TerminateThread(threadhandle,0);
	runningmutex.Unlock();
}